/**
 * Copyright (c) 2015-2017, Henry Yang 杨勇 (gismail@foxmail.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lambkit.module.cms;

import com.jfinal.config.Interceptors;
import com.jfinal.config.Routes;
import com.jfinal.kit.StrKit;
import com.jfinal.template.Engine;
import com.lambkit.Lambkit;
import com.lambkit.common.service.ServiceManager;
import com.lambkit.common.util.ScanJarStringSource;
import com.lambkit.core.rpc.RpcConfig;
import com.lambkit.db.datasource.ActiveRecordPluginWrapper;
import com.lambkit.module.LambkitModule;

import com.lambkit.module.cms.rpc.model.CmsArticle;
import com.lambkit.module.cms.rpc.model.CmsCategory;
import com.lambkit.module.cms.rpc.model.CmsComment;
import com.lambkit.module.cms.rpc.model.CmsFavorite;
import com.lambkit.module.cms.rpc.model.CmsFile;
import com.lambkit.module.cms.rpc.model.CmsAccess;
import com.lambkit.module.cms.rpc.model.CmsMenu;
import com.lambkit.module.cms.rpc.model.CmsMessage;
import com.lambkit.module.cms.rpc.model.CmsPage;
import com.lambkit.module.cms.rpc.model.CmsRelation;
import com.lambkit.module.cms.rpc.model.CmsSetting;
import com.lambkit.module.cms.rpc.model.CmsSystem;
import com.lambkit.module.cms.rpc.model.CmsTag;
import com.lambkit.module.cms.rpc.model.CmsTopic;
import com.lambkit.module.cms.rpc.api.CmsArticleService;
import com.lambkit.module.cms.common.CmsConfig;
import com.lambkit.module.cms.core.km.Km;
import com.lambkit.module.cms.core.search.SearcherKit;
import com.lambkit.module.cms.core.search.impl.LuceneFileSearcher;
import com.lambkit.module.cms.core.search.impl.LuceneSearcher;
import com.lambkit.module.cms.core.template.TemplateManager;
import com.lambkit.module.cms.rpc.api.CmsCategoryService;
import com.lambkit.module.cms.rpc.api.CmsCommentService;
import com.lambkit.module.cms.rpc.api.CmsFavoriteService;
import com.lambkit.module.cms.rpc.api.CmsAccessService;
import com.lambkit.module.cms.rpc.api.CmsFileService;
import com.lambkit.module.cms.rpc.api.CmsMenuService;
import com.lambkit.module.cms.rpc.api.CmsMessageService;
import com.lambkit.module.cms.rpc.api.CmsPageService;
import com.lambkit.module.cms.rpc.api.CmsScoreService;
import com.lambkit.module.cms.rpc.api.CmsRelationService;
import com.lambkit.module.cms.rpc.api.CmsSettingService;
import com.lambkit.module.cms.rpc.api.CmsSystemService;
import com.lambkit.module.cms.rpc.api.CmsTagService;
import com.lambkit.module.cms.rpc.api.CmsTopicService;
import com.lambkit.module.cms.rpc.service.impl.CmsArticleServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsArticleServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsCategoryServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsCategoryServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsCommentServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsCommentServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsFavoriteServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsFavoriteServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsAccessServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsAccessServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsFileServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsFileServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsMenuServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsMenuServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsMessageServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsMessageServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsPageServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsPageServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsScoreServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsRelationServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsRelationServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsScoreServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsSettingServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsSettingServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsSystemServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsSystemServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsTagServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsTagServiceMock;
import com.lambkit.module.cms.rpc.service.impl.CmsTopicServiceImpl;
import com.lambkit.module.cms.rpc.service.impl.CmsTopicServiceMock;
import com.lambkit.module.cms.web.tag.CmsArticleMarker;
import com.lambkit.module.cms.web.tag.CmsCategoryMarker;
import com.lambkit.module.cms.web.tag.CmsCommentMarker;
import com.lambkit.module.cms.web.tag.CmsFavoriteMarker;
import com.lambkit.module.cms.web.tag.CmsAccessMarker;
import com.lambkit.module.cms.web.tag.CmsFileMarker;
import com.lambkit.module.cms.web.tag.CmsMenuMarker;
import com.lambkit.module.cms.web.tag.CmsMessageMarker;
import com.lambkit.module.cms.web.tag.CmsPageMarker;
import com.lambkit.module.cms.web.tag.CmsRelationMarker;
import com.lambkit.module.cms.web.tag.CmsSettingMarker;
import com.lambkit.module.cms.web.tag.CmsSystemMarker;
import com.lambkit.module.cms.web.tag.CmsTagMarker;
import com.lambkit.module.cms.web.tag.CmsTopicMarker;
import com.lambkit.module.cms.web.directive.CmsArticleDirective;
import com.lambkit.module.cms.web.directive.CmsCategoryDirective;
import com.lambkit.module.cms.web.directive.CmsCommentDirective;
import com.lambkit.module.cms.web.directive.CmsFavoriteDirective;
import com.lambkit.module.cms.web.directive.CmsAccessDirective;
import com.lambkit.module.cms.web.directive.CmsFileDirective;
import com.lambkit.module.cms.web.directive.CmsMenuDirective;
import com.lambkit.module.cms.web.directive.CmsMessageDirective;
import com.lambkit.module.cms.web.directive.CmsPageDirective;
import com.lambkit.module.cms.web.directive.CmsRelationDirective;
import com.lambkit.module.cms.web.directive.CmsSettingDirective;
import com.lambkit.module.cms.web.directive.CmsSystemDirective;
import com.lambkit.module.cms.web.directive.CmsTagDirective;
import com.lambkit.module.cms.web.directive.CmsTopicDirective;
import com.lambkit.module.cms.web.directive.TagsDirective;

/**
 * @author yangyong 
 * @website: www.lambkit.com
 * @email: gismail@foxmail.com
 * @date 2019-10-22
 * @version 1.0
 * @since 1.0
 */
public class CmsModule extends LambkitModule  {

	@Override
	public void configMapping(ActiveRecordPluginWrapper arp) {
		if(StrKit.isBlank(getConfig().getDbconfig())) {
			mapping(arp);
		}
	}
	
	@Override
	public void configMapping(String name, ActiveRecordPluginWrapper arp) {
		super.configMapping(name, arp);
		if(StrKit.notBlank(name) && name.equals(getConfig().getDbconfig())) {
			mapping(arp);
		}
	}
	
	@Override
	public void configRoute(Routes me) {
		// TODO Auto-generated method stub
		me.add(new CmsAdminRoutes());
		me.add(new CmsWebRoutes());
	}
	
	@Override
	public void configEngine(Engine me) {
		// TODO Auto-generated method stub
		addDirective(me, "cmsArticle", CmsArticleDirective.class);
		addDirective(me, "cmsCategory", CmsCategoryDirective.class);
		addDirective(me, "cmsComment", CmsCommentDirective.class);
		addDirective(me, "cmsMenu", CmsMenuDirective.class);
		addDirective(me, "cmsPage", CmsPageDirective.class);
		addDirective(me, "cmsSetting", CmsSettingDirective.class);
		addDirective(me, "cmsSystem", CmsSystemDirective.class);
		addDirective(me, "cmsTag", CmsTagDirective.class);
		addDirective(me, "cmsTopic", CmsTopicDirective.class);
		addDirective(me, "cmsFavorite", CmsFavoriteDirective.class);
		addDirective(me, "cmsFile", CmsFileDirective.class);
		addDirective(me, "cmsRelation", CmsRelationDirective.class);
		addDirective(me, "cmsMessage", CmsMessageDirective.class);
		addDirective(me, "cmsAccess", CmsAccessDirective.class);
		registerEngine(me, "com.lambkit.module.cms.web.directive");
	}
	
	@Override
	public void configInterceptor(Interceptors me) {
	}

	@Override
	public void onStart() {
		// TODO Auto-generated method stub
		addFreeMarker(this);
		if("server".equals(getConfig().getServerType())) {
			registerLocalService();
		} else if("client".equals(getConfig().getServerType())) {
			registerRemoteService();
		} 
		//模板管理引擎初始化
		TemplateManager.me().init();
		//初始化文章搜索引擎
		SearcherKit.initArticleSearcher(LuceneSearcher.class);
		//初始化文件搜索引擎
		SearcherKit.initFileSearcher(LuceneFileSearcher.class);
		//知识管理引擎初始化
		Km.init();
	}
	
	@Override
	public void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
		Km.close();
	}
	
	public void mapping(ActiveRecordPluginWrapper arp) {
		arp.addSqlTemplate(new ScanJarStringSource("cms.sql"));
		
		arp.addMapping("cms_article", "article_id", CmsArticle.class);
		//arp.addMapping("cms_article_category", "article_category_id", CmsArticleCategory.class);
		//arp.addMapping("cms_article_tag", "article_tag_id", CmsArticleTag.class);
		arp.addMapping("cms_category", "category_id", CmsCategory.class);
		//arp.addMapping("cms_category_tag", "category_tag_id", CmsCategoryTag.class);
		arp.addMapping("cms_comment", "comment_id", CmsComment.class);
		arp.addMapping("cms_menu", "menu_id", CmsMenu.class);
		arp.addMapping("cms_page", "page_id", CmsPage.class);
		arp.addMapping("cms_setting", "setting_id", CmsSetting.class);
		arp.addMapping("cms_system", "system_id", CmsSystem.class);
		arp.addMapping("cms_tag", "tag_id", CmsTag.class);
		arp.addMapping("cms_topic", "topic_id", CmsTopic.class);
		arp.addMapping("cms_favorite", "favorite_id", CmsFavorite.class);
		arp.addMapping("cms_file", "file_id", CmsFile.class);
		//arp.addMapping("cms_file_catelog", "file_category_id", CmsFileCatelog.class);
		//arp.addMapping("cms_file_tag", "file_tag_id", CmsFileTag.class);
		arp.addMapping("cms_relation", "main_id,relation_id", CmsRelation.class);
		arp.addMapping("cms_message", "message_id", CmsMessage.class);
		arp.addMapping("cms_access", "access_id", CmsAccess.class);
	}
	
	public void addFreeMarker(LambkitModule lk) {
		lk.addTag("article", new CmsArticleMarker());
		lk.addTag("category", new CmsCategoryMarker());
		lk.addTag("comment", new CmsCommentMarker());
		lk.addTag("menu", new CmsMenuMarker());
		lk.addTag("page", new CmsPageMarker());
		lk.addTag("setting", new CmsSettingMarker());
		lk.addTag("system", new CmsSystemMarker());
		lk.addTag("tag", new CmsTagMarker());
		lk.addTag("topic", new CmsTopicMarker());
		lk.addTag("favorite", new CmsFavoriteMarker());
		lk.addTag("file", new CmsFileMarker());
		lk.addTag("relation", new CmsRelationMarker());
		lk.addTag("message", new CmsMessageMarker());
		lk.addTag("access", new CmsAccessMarker());
	}
			
	public void registerLocalService() {
		registerLocalService(getRpcGroup(), getRpcVersion(), getRpcPort());
	}
	
	public void registerLocalService(String group, String version, int port) {
		ServiceManager.me().mapping(CmsArticleService.class, CmsArticleServiceImpl.class, CmsArticleServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsCategoryService.class, CmsCategoryServiceImpl.class, CmsCategoryServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsCommentService.class, CmsCommentServiceImpl.class, CmsCommentServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsMenuService.class, CmsMenuServiceImpl.class, CmsMenuServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsPageService.class, CmsPageServiceImpl.class, CmsPageServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsSettingService.class, CmsSettingServiceImpl.class, CmsSettingServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsSystemService.class, CmsSystemServiceImpl.class, CmsSystemServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsTagService.class, CmsTagServiceImpl.class, CmsTagServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsTopicService.class, CmsTopicServiceImpl.class, CmsTopicServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsFavoriteService.class, CmsFavoriteServiceImpl.class, CmsFavoriteServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsFileService.class, CmsFileServiceImpl.class, CmsFileServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsAccessService.class, CmsAccessServiceImpl.class, CmsAccessServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsRelationService.class, CmsRelationServiceImpl.class, CmsRelationServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsMessageService.class, CmsMessageServiceImpl.class, CmsMessageServiceMock.class, group, version, port);
		ServiceManager.me().mapping(CmsScoreService.class, CmsScoreServiceImpl.class, CmsScoreServiceMock.class, group, version, port);
	}
	
	public void registerRemoteService() {
		registerRemoteService(getRpcGroup(), getRpcVersion(), getRpcPort());
	}
	
	public void registerRemoteService(String group, String version, int port) {
		ServiceManager.me().remote(CmsArticleService.class, CmsArticleServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsCategoryService.class, CmsCategoryServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsCommentService.class, CmsCommentServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsMenuService.class, CmsMenuServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsPageService.class, CmsPageServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsSettingService.class, CmsSettingServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsSystemService.class, CmsSystemServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsTagService.class, CmsTagServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsTopicService.class, CmsTopicServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsFavoriteService.class, CmsFavoriteServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsFileService.class, CmsFileServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsAccessService.class, CmsAccessServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsRelationService.class, CmsRelationServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsMessageService.class, CmsMessageServiceMock.class, group, version, port);
		ServiceManager.me().remote(CmsScoreService.class, CmsScoreServiceMock.class, group, version, port);
	}
	
	public int getRpcPort() {
		return Lambkit.config(RpcConfig.class).getDefaultPort();
	}
	
	public String getRpcGroup() {
		return Lambkit.config(RpcConfig.class).getDefaultGroup();
	}
	
	public String getRpcVersion() {
		return getConfig().getVersion();
	}
	
	public CmsConfig getConfig() {
		return Lambkit.config(CmsConfig.class);
	}
}

